home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Media 22
/
PC MEDIA CD22.iso
/
share
/
prog
/
spm220e
/
starintf.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-10-08
|
38KB
|
1,636 lines
{
╔═════════════════════════════════════════════════════════════════════════════╗
║ NAME : STARINTF.PAS ║
║ FUNCTION : Interfacing functions and procedures for the serial driver ║
║ : STARCOMM.EXE. PASCAL Language listing for STARCOMM used as a ║
║ : simple T.S.R. BIOS, or as a DOS DEVICE DRIVER, or as a library. ║
║ VERSION : 2.20 ║
║ LANGUAGE : TURBO PASCAL v4.0 and laters (Developed as a "UNIT"...). ║
║ REMARKS : If an application program calls the functions to access the ║
║ : serial ports whereas "RS_accessible=FALSE" (or "COMM_ouvert= ║
║ : FALSE" for the DEVICE DRIVER interfacing), the returned codes ║
║ : won't have ANY MEANING... These calls to the driver won't have ║
║ : any effect in such a case. ║
║ : In order to use the "library" mode, ativate the lines labeled ║
║ : "--- LIBRARY ---"... ║
║ : Please, report yourself to STAR_REF.DOC to get any information ║
║ : you need on these procedures... ║
║ COPYRIGHT : HETRU Fabrice 1991-1995. ║
╚═════════════════════════════════════════════════════════════════════════════╝
}
UNIT StarIntf;
interface
USES Dos;
(* --- LIBRARY --- *)
(* To use the "library" mode of STARCOMM, activate the *)
(* following line: *)
(* {$L SCLIB.OBJ} *)
(* --------------- *)
TYPE
Chn4octets = STRING[4] ;
CONST
(* Serial port to be managed by the called function: 0 (COM1:)...7 (COM8:) *)
CommPort : WORD = 0 ;
(* Array to store which serial ports are acknowledged, and which are NOT. *)
(* This array is up-dated from the "Port_Opened" routine. *)
ComExist : ARRAY[0..7] OF BOOLEAN=(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE);
(* 8250 basics adresses for the COM1 to COM4 serial ports ? *)
BasePort1 : WORD = $3F8;
BasePort2 : WORD = $2F8;
BasePort3 : WORD = $3E8;
BasePort4 : WORD = $2E8;
(* Possibles values for the hard hand-shaking activating flag. *)
RTS_CTS : BYTE = 1;
DTR_DSR : BYTE = 2;
BothCmde : BYTE = 3;
RI : BYTE = 4;
DCD : BYTE = 5;
OUT1 : BYTE = 6;
(* Possibles values for the hard hand-shaking working mode flag. *)
Inactif : BYTE = 0;
Local : BYTE = 76; (*'L'*)
Eloigne : BYTE = 69; (*'E'*)
Bilateral : BYTE = 66; (*'B'*)
(* Codes to be used as soft hand-shaking control signals. *)
Xon : BYTE = $11;
Xoff : BYTE = $13;
(* Possibles values for the errors substitution process working mode. *)
NonActif : BYTE = 0; (* Smode0: Erroneous bytes will be stored in the *)
(* receiving buffer exactly as they are decoded. *)
Remplace : BYTE = 1; (* Smode1: U/S bytes are subtitued with special code. *)
RempNULL : BYTE = 2; (* Smode2: U/S bytes are lost. The lost bytes counter *)
(* is incremented for each erroneous byte lost. *)
NoBreakBuff : BYTE = 100; (* Bmode0: Pas de code de BREAK en buffer de rcp *)
BreakOnBuff : BYTE = 200; (* Bmode1: Code spécial de BREAK voulu en rcp... *)
(* DEVICE DRIVER name associated with STARCOMM.EXE. *)
NomDevice : STRING[8] = 'COMM ';
(* Computer architectural type (used for the IRQs authorizations...). *)
Type_PC : BYTE = 1;
Type_XT : BYTE = 2;
Type_AT : BYTE = 3;
PS2_PC : BYTE = 4;
PS2_AT : BYTE = 5;
VAR
RS_accessible : BOOLEAN ; (* TRUE=Driver in RAM, FALSE=Driver NOT in RAM *)
type_driver : BYTE ; (* 0=Not here,1= BIOS mode, 2= DEV-DRV mode. *)
handler_voie_serie : WORD ; (* "COMM" File handler. *)
COMM_ouvert : BOOLEAN ; (* File status flag for the "COMM" dev. driver.*)
Serial_error : WORD ; (* DOS error code received at the opening... *)
(* --- LIBRARY --- *)
(* To use the "library" mode of STARCOMM, activate the *)
(* following procedures: *)
(* PROCEDURE Set_SCL; *)
(* PROCEDURE UnSetSCL; *)
(* PROCEDURE SCLservs; *)
(* --------------- *)
(* Functions to be reached using the interrupt 14h. *)
PROCEDURE Version(VAR NumVer: Chn4octets);
FUNCTION Open_Port: BYTE;
FUNCTION OpenPort_Buff(Segment,Offset,Taille_in,Taille_out: WORD): BYTE;
FUNCTION Close_Port(ProtegeBuff: BOOLEAN): BYTE;
FUNCTION Port_Opened: BOOLEAN;
FUNCTION Interdit_Port: BYTE;
FUNCTION Autorise_Port: BYTE;
FUNCTION EtatVerrouilleComm(VAR Mode: BYTE): BYTE;
FUNCTION VerrouilleComm(Mode: BYTE): BYTE;
FUNCTION SLOW_Ems: BYTE;
FUNCTION FAST_Ems: BYTE;
FUNCTION Send_SLOW: BOOLEAN;
PROCEDURE Get_Ports_Adresses;
FUNCTION Infos_Uart(VAR Uart_type: BYTE; VAR Uart_adresse: WORD;
VAR Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
FUNCTION Set_New_Uart(Uart_adresse: WORD;
Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
PROCEDURE Infos_Buffs(VAR Nb_actifs, Nb_maxi: BYTE;
VAR Taille_InBuff,Taille_OutBuff: WORD);
FUNCTION Init_Port(longueur, stop_bit, parity: CHAR; vitesse: LONGINT;
VAR Taille_InBuff: WORD; VAR Taille_OutBuff: WORD): BYTE;
PROCEDURE Init_status(VAR Format: WORD);
FUNCTION Reset_Init_status(Format: WORD): BYTE;
PROCEDURE Flush_buffers;
PROCEDURE Flush_InBuff;
PROCEDURE Flush_OutBuff;
PROCEDURE ResetPort_and_TimMAX(RdTim_MAX: BYTE; VAR Old_RdTim_MAX: BYTE;
WrTim_MAX: BYTE; VAR Old_WrTim_MAX: BYTE);
PROCEDURE Status_Trait_Erreurs(VAR mode: BYTE; VAR codeEr, codeBk: CHAR);
FUNCTION Def_Trait_Erreurs(mode: BYTE; code: CHAR): BYTE;
FUNCTION Change_com_port(Num_port: BYTE): BYTE;
FUNCTION Attend_Buff_ems_vide(Temps_maxi: BYTE): BOOLEAN;
FUNCTION CheckBufferIn(VAR nb_a_lire: WORD): BOOLEAN;
FUNCTION CheckBufferOut(VAR place_libre: WORD): BOOLEAN;
FUNCTION ReadSerie(VAR c: CHAR; nombre: WORD; VAR Nb_received: WORD): BYTE;
FUNCTION WriteSerie(VAR c: CHAR; nombre: WORD; VAR Nb_written: WORD): BYTE;
FUNCTION ReadCarSerie(VAR c: CHAR): BYTE;
FUNCTION WriteCarSerie(c: CHAR): BYTE;
FUNCTION Peek_rcp(VAR c: CHAR): BYTE;
FUNCTION Poke_rcp(c: CHAR): BYTE;
FUNCTION WriteCmde(VAR Cmde: CHAR; nombre: BYTE; UseDTR: BOOLEAN): BYTE;
PROCEDURE Etat_du_Modem(VAR Voie_active: CHAR; VAR Pret, Clear_to_send,
Sonnerie, Porteuse, Changements: BOOLEAN; VAR deltaDSR, deltaCTS,
deltaRI, deltaDCD: BYTE);
PROCEDURE Set_DTR;
PROCEDURE Clear_DTR;
PROCEDURE Set_RTS;
PROCEDURE Clear_RTS;
PROCEDURE Set_OUT1;
PROCEDURE Clear_OUT1;
PROCEDURE Send_break(duree: BYTE);
FUNCTION Errors_Report(VAR Buff_overflow, Engorgement, Parite, Stop_bit,
Break_it: BYTE): BOOLEAN;
FUNCTION Port_Free: BOOLEAN;
FUNCTION HandShake_Status(Proto_type: BYTE;VAR SendEnabled: BOOLEAN): BYTE;
PROCEDURE HandShake_Setup(Proto_type: BYTE; state: BYTE);
FUNCTION XonoffShaking_Status(VAR SendEnabled: BOOLEAN;
VAR Nb_Xoff: BYTE): BYTE;
PROCEDURE XonoffShaking_Setup(state: BYTE);
PROCEDURE Set_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
PROCEDURE Reset_routine(Segment,Offset: WORD);
PROCEDURE Unset_routine;
PROCEDURE Set_err_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
PROCEDURE Reset_err_routine(Segment,Offset: WORD);
PROCEDURE Unset_err_routine;
PROCEDURE Verrouille;
PROCEDURE Deverrouille;
FUNCTION GetDeviceName: BYTE;
FUNCTION GetPortDevice: BYTE;
FUNCTION ResetPortDevice: BYTE;
FUNCTION EmulBIOS: BOOLEAN;
PROCEDURE SetEmulBIOS(status: BOOLEAN);
FUNCTION OrdiType: BYTE;
PROCEDURE SetOrdiType(OrdiType: BYTE);
(* Functions to be reached using the DOS interrupt 21h (DEVICE DRIVER mode). *)
FUNCTION Open_COMM: WORD;
FUNCTION Close_COMM: INTEGER;
FUNCTION IOStream_READ(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
FUNCTION IOStream_WRITE(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
FUNCTION CheckCOMMIn: BOOLEAN;
FUNCTION CheckCOMMOut: BOOLEAN;
FUNCTION ReadCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
FUNCTION WriteCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
(* Function to scan STARCOMM.EXE in memory. *)
FUNCTION Check_STARCOMM_Present: BYTE;
implementation
VAR
reg88 : Registers ;
(* --- LIBRARY --- *)
(* To use the "library" mode of STARCOMM, activate the *)
(* following procedures: *)
(* *)
(* PROCEDURE Set_SCL; External; *)
(* *)
(* PROCEDURE UnSetSCL; External; *)
(* *)
(* PROCEDURE SCLservs; External; *)
(* --------------- *)
PROCEDURE Version(VAR NumVer: Chn4octets);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := 6;
Intr($14,Dos.Registers(reg88));
NumVer[1] := chr(al);
NumVer[2] := '.';
ax := di;
NumVer[3] := chr(ah);
NumVer[4] := chr(al)
END;
NumVer[0] := chr(4);
END
ELSE NumVer[0] := chr(0);
END;
FUNCTION Open_Port: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 0;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Open_Port := ah
END;
END
END;
FUNCTION OpenPort_Buff(Segment,Offset,Taille_in,Taille_out: WORD): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 6;
dx := CommPort;
es := Segment;
di := Offset;
bx := Taille_in;
cx := Taille_out;
Intr($14,Dos.Registers(reg88));
OpenPort_Buff := ah
END;
END
END;
FUNCTION Close_Port(ProtegeBuff: BOOLEAN): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
IF ProtegeBuff THEN al := 1 ELSE al := 7;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Close_Port := ah
END;
END
END;
FUNCTION Port_Opened: BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 2;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
IF CommPort<8 THEN
BEGIN
IF ah=5 THEN ComExist[CommPort] := FALSE
ELSE ComExist[CommPort] := TRUE
END;
IF al=1 THEN Port_Opened := TRUE
ELSE Port_Opened := FALSE
END;
END
END;
FUNCTION Interdit_Port: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $0A;
al := 0;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Interdit_Port := ah
END;
END
END;
FUNCTION Autorise_Port: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $0A;
al := 1;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Autorise_Port := ah
END;
END
END;
FUNCTION EtatVerrouilleComm(VAR Mode: BYTE): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $0A;
al := 6;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Mode := al;
EtatVerrouilleComm := ah
END;
END
END;
FUNCTION VerrouilleComm(Mode: BYTE): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $0A;
al := Mode;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
VerrouilleComm := ah
END;
END
END;
FUNCTION SLOW_Ems: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 3;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
SLOW_Ems := ah
END;
END
END;
FUNCTION FAST_Ems: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 4;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
FAST_Ems := ah
END;
END
END;
FUNCTION Send_SLOW: BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $07;
al := 5;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
IF al=1 THEN Send_SLOW := TRUE
ELSE Send_SLOW := FALSE
END;
END
END;
PROCEDURE Get_Ports_Adresses;
BEGIN
BasePort1 := MEMW[$40:$00];
BasePort2 := MEMW[$40:$02];
BasePort3 := MEMW[$40:$04];
BasePort4 := MEMW[$40:$06]
END;
FUNCTION Infos_Uart(VAR Uart_type: BYTE; VAR Uart_adresse: WORD;
VAR Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
reg88.ah := $09;
reg88.al := 0;
reg88.dx := CommPort;
Intr($14,Dos.Registers(reg88));
Uart_type := reg88.al;
Uart_adresse := reg88.bx;
Irq := reg88.ch;
IF reg88.cl=0 THEN
BEGIN
FIFO_actif := 0;
Taille_FIFO := 1;
END
ELSE
BEGIN
FIFO_actif := 1;
Taille_FIFO := reg88.cl
END;
Infos_Uart := reg88.ah;
END
END;
FUNCTION Set_New_Uart(Uart_adresse: WORD;
Irq,FIFO_actif,Taille_FIFO: BYTE): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
reg88.ah := $09;
reg88.al := 1;
reg88.dx := CommPort;
reg88.bx := Uart_adresse;
reg88.ch := Irq;
IF FIFO_actif=1 THEN reg88.cl := Taille_FIFO
ELSE reg88.cl := 0;
Intr($14,Dos.Registers(reg88));
Set_New_Uart := reg88.ah;
END
END;
PROCEDURE Infos_Buffs(VAR Nb_actifs, Nb_maxi: BYTE;
VAR Taille_InBuff,Taille_OutBuff: WORD);
BEGIN
IF RS_accessible THEN
BEGIN
reg88.ah := $0D;
Intr($14,Dos.Registers(reg88));
Taille_InBuff := reg88.bx;
Taille_OutBuff := reg88.cx;
Nb_actifs := reg88.dh;
Nb_maxi := reg88.dl;
END
END;
FUNCTION Init_Port(longueur, stop_bit, parity: CHAR; vitesse: LONGINT;
VAR Taille_InBuff: WORD; VAR Taille_OutBuff: WORD): BYTE;
VAR
descripteur_format, vitess : BYTE ;
BEGIN
Init_Port := 1;
WITH reg88 DO
BEGIN
CASE longueur OF
'5': descripteur_format := $00;
'6': descripteur_format := $01;
'7': descripteur_format := $02;
'8': descripteur_format := $03;
ELSE Exit
END;
CASE stop_bit OF
'1': ;
'2': descripteur_format := descripteur_format + $04;
ELSE Exit
END;
CASE upcase(parity) OF
'N': ;
'I': descripteur_format := descripteur_format + 8;
'P': descripteur_format := descripteur_format + 24;
'T': descripteur_format := descripteur_format + 40;
'R': descripteur_format := descripteur_format + 56;
ELSE Exit
END;
IF vitesse=110 THEN vitess := 0
ELSE IF vitesse=150 THEN vitess := 1
ELSE IF vitesse=300 THEN vitess := 2
ELSE IF vitesse=600 THEN vitess := 3
ELSE IF vitesse=1200 THEN vitess := 4
ELSE IF vitesse=2400 THEN vitess := 5
ELSE IF vitesse=4800 THEN vitess := 6
ELSE IF vitesse=9600 THEN vitess := 7
ELSE IF vitesse=19200 THEN vitess := 8
ELSE IF vitesse=28800 THEN vitess := 9
ELSE IF vitesse=38400 THEN vitess := 10
ELSE IF vitesse=57600 THEN vitess := 11
ELSE IF vitesse=115200 THEN vitess := 12
ELSE Exit;
bl := descripteur_format;
bh := vitess;
dx := CommPort;
ah := $0B;
IF RS_accessible THEN
BEGIN
Intr($14,Dos.Registers(reg88));
Taille_InBuff := bx;
Taille_OutBuff := cx;
Init_Port := 0;
END
ELSE Init_Port := 2;
END
END;
PROCEDURE Init_status(VAR Format: WORD);
VAR
Mem_Variable : ARRAY[1..3] OF BYTE ;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
es := Seg(Mem_Variable[1]);
di := Ofs(Mem_Variable[1]);
dx := CommPort;
ah := $0C;
Intr($14,Dos.Registers(reg88))
END;
Format := (Mem_Variable[2]*256) + Mem_Variable[3];
END
END;
FUNCTION Reset_Init_status(Format: WORD): BYTE;
BEGIN
WITH reg88 DO
BEGIN
bx := Format;
dx := CommPort;
ah := $0B;
IF RS_accessible THEN
BEGIN
Intr($14,Dos.Registers(reg88));
IF ah=0 THEN Reset_Init_status := 0
ELSE Reset_Init_status := 1;
END
ELSE Reset_Init_status := 2;
END
END;
PROCEDURE Flush_buffers;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
dx := CommPort;
ah := $0E;
Intr($14,Dos.Registers(reg88));
END;
END
END;
PROCEDURE Flush_InBuff;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
dx := CommPort;
ah := $0F;
Intr($14,Dos.Registers(reg88));
END;
END
END;
PROCEDURE Flush_OutBuff;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
dx := CommPort;
ah := $10;
Intr($14,Dos.Registers(reg88));
END;
END
END;
PROCEDURE ResetPort_and_TimMAX(RdTim_MAX: BYTE; VAR Old_RdTim_MAX: BYTE;
WrTim_MAX: BYTE; VAR Old_WrTim_MAX: BYTE);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $11;
bh := RdTim_MAX;
bl := WrTim_MAX;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Old_RdTim_MAX := bh;
Old_WrTim_MAX := bl
END;
END
END;
PROCEDURE Status_Trait_Erreurs(VAR mode: BYTE; VAR codeEr, codeBk: CHAR);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $12;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
mode := al;
codeEr := Chr(bl);
codeBk := Chr(bh);
END;
END
END;
FUNCTION Def_Trait_Erreurs(mode: BYTE; code: CHAR): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := mode;
bl := Ord(code);
dx := CommPort;
ah := $13;
Intr($14,Dos.Registers(reg88));
Def_Trait_Erreurs := ah
END;
END
END;
FUNCTION Change_com_port(Num_port: BYTE): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
CommPort := Num_port;
dx := CommPort;
ah := $08;
Intr($14,Dos.Registers(reg88));
Change_com_port := ah
END;
END
END;
FUNCTION Attend_Buff_ems_vide(Temps_maxi: BYTE): BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $1B;
al := Temps_maxi;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
IF ah=4 THEN Attend_Buff_ems_vide := FALSE
ELSE Attend_Buff_ems_vide := TRUE;
END;
END
END;
FUNCTION CheckBufferIn(VAR nb_a_lire: WORD): BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $1C;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
nb_a_lire := cx;
IF (ah=0) AND (al=0) THEN CheckBufferIn := TRUE
ELSE CheckBufferIn := FALSE;
END;
END
ELSE CheckBufferIn := FALSE;
END;
FUNCTION CheckBufferOut(VAR place_libre: WORD): BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $1D;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
place_libre := cx;
IF (ah=0) AND (al=0) THEN CheckBufferOut := TRUE
ELSE CheckBufferOut := FALSE;
END;
END
ELSE CheckBufferOut := FALSE;
END;
FUNCTION ReadSerie(VAR c: CHAR; nombre: WORD; VAR Nb_received: WORD): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $14;
es := Seg(c);
di := Ofs(c);
cx := nombre;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Nb_received := cx;
ReadSerie := ah
END;
END
END;
FUNCTION WriteSerie(VAR c: CHAR; nombre: WORD; VAR Nb_written: WORD): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $15;
es := Seg(c);
di := Ofs(c);
cx := nombre;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Nb_written := cx;
WriteSerie := ah
END;
END
END;
FUNCTION ReadCarSerie(VAR c: CHAR): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $16;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
c := Chr(al);
ReadCarSerie := ah
END;
END
END;
FUNCTION WriteCarSerie(c: CHAR): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $17;
al := Ord(c);
dx := CommPort;
Intr($14,Dos.Registers(reg88));
WriteCarSerie := ah
END;
END
END;
FUNCTION Peek_rcp(VAR c: CHAR): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $18;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
c := Chr(al);
Peek_rcp := ah
END;
END
END;
FUNCTION Poke_rcp(c: CHAR): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $19;
al := Ord(c);
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Poke_rcp := ah
END;
END
END;
FUNCTION WriteCmde(VAR Cmde: CHAR; nombre: BYTE; UseDTR: BOOLEAN): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $1A;
es := Seg(Cmde);
di := Ofs(Cmde);
al := nombre;
IF UseDTR THEN bh := 1 ELSE bh := 0;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
WriteCmde := ah
END;
END
END;
PROCEDURE Etat_du_Modem(VAR Voie_active: CHAR; VAR Pret, Clear_to_send,
Sonnerie, Porteuse, Changements: BOOLEAN; VAR deltaDSR, deltaCTS,
deltaRI, deltaDCD: BYTE);
VAR
Mem_Variable : ARRAY[1..10] OF BYTE ;
voie_num : CHAR absolute Mem_Variable ;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
es := Seg(Mem_Variable[1]);
di := Ofs(Mem_Variable[1]);
dx := CommPort;
ah := $20;
al := 0;
Intr($14,Dos.Registers(reg88))
END;
Mem_Variable[1] := Mem_Variable[1] + $31;
Voie_active := voie_num;
IF Mem_Variable[2]=1 THEN Pret := TRUE
ELSE Pret := FALSE;
IF Mem_Variable[3]=1 THEN Clear_to_send := TRUE
ELSE Clear_to_send := FALSE;
IF Mem_Variable[4]=1 THEN Sonnerie := TRUE
ELSE Sonnerie := FALSE;
IF Mem_Variable[5]=1 THEN Porteuse := TRUE
ELSE Porteuse := FALSE;
IF Mem_Variable[6]=1 THEN Changements := TRUE
ELSE Changements := FALSE;
deltaDSR := Mem_Variable[7];
deltaCTS := Mem_Variable[8];
deltaRI := Mem_Variable[9];
deltaDCD := Mem_Variable[10];
END
END;
PROCEDURE Set_DTR;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $01;
dx := CommPort;
ah := $20;
al := 1;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Clear_DTR;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $FE;
dx := CommPort;
ah := $20;
al := 2;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Set_RTS;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $02;
dx := CommPort;
ah := $20;
al := 1;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Clear_RTS;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $FD;
dx := CommPort;
ah := $20;
al := 2;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Set_OUT1;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $04;
dx := CommPort;
ah := $20;
al := 1;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Clear_OUT1;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
di := $FB;
dx := CommPort;
ah := $20;
al := 2;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Send_break(duree: BYTE);
BEGIN
IF RS_accessible THEN
BEGIN
reg88.bl := duree;
reg88.ah := $1E;
reg88.dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
END;
FUNCTION Errors_Report(VAR Buff_overflow, Engorgement, Parite,
Stop_bit, Break_it: BYTE): BOOLEAN;
VAR
Mem_Variable : ARRAY[1..5] OF BYTE ;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
es := Seg(Mem_Variable[1]);
di := Ofs(Mem_Variable[1]);
dx := CommPort;
ah := $1F;
Intr($14,Dos.Registers(reg88))
END;
Buff_overflow := Mem_Variable[1];
Engorgement := Mem_Variable[2];
Parite := Mem_Variable[3];
Stop_bit := Mem_Variable[4];
Break_it := Mem_Variable[5];
IF (reg88.al=0) THEN Errors_Report := FALSE
ELSE Errors_Report := TRUE;
END
END;
FUNCTION Port_Free: BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $25;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
IF (reg88.al=0) THEN Port_Free := FALSE
ELSE Port_Free := TRUE;
END
END;
FUNCTION HandShake_Status(Proto_type: BYTE;VAR SendEnabled: BOOLEAN): BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $21;
al := Proto_type;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
IF (reg88.di=0) THEN SendEnabled := FALSE
ELSE SendEnabled := TRUE;
HandShake_status := reg88.al;
END
END;
PROCEDURE HandShake_Setup(Proto_type: BYTE; state: BYTE);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $22;
al := Proto_type;
state := state AND $DF;
IF state IN [Inactif,Local,Eloigne,Bilateral] THEN
bh := state
ELSE bh := 0;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
END
END;
FUNCTION XonoffShaking_Status(VAR SendEnabled: BOOLEAN;
VAR Nb_Xoff: BYTE): BYTE;
VAR
Mem_Variable : ARRAY[1..5] OF BYTE ;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
es := Seg(Mem_Variable[1]);
di := Ofs(Mem_Variable[1]);
dx := CommPort;
ah := $23;
Intr($14,Dos.Registers(reg88))
END;
Xon := Mem_Variable[1];
Xoff := Mem_Variable[2];
Nb_Xoff := Mem_Variable[3];
IF (Mem_Variable[4]=Xon) THEN SendEnabled := TRUE
ELSE SendEnabled := FALSE;
XonoffShaking_Status := Mem_Variable[5];
END
END;
PROCEDURE XonoffShaking_Setup(state: BYTE);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $24;
state := state AND $DF;
IF state IN [Inactif,Local,Eloigne,Bilateral] THEN
al := state
ELSE al := 0;
bh := Xon;
bl := Xoff;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
END
END;
(* Define here any local variable you need for your user-routine: *)
(* VAR <.....> *)
PROCEDURE Routine; INTERRUPT;
(* !! ATTENTION !! DO NOT DEFINE ANY VARIABLE HERE *)
BEGIN
(* Install here the routine to be called by the driver. *)
(* ... *)
(* The following special code MUST NOT BE CHANGED !... *)
INLINE($89/$EC (* mov sp,bp *)
/$5D (* pop bp *)
/$07 (* pop es *)
/$1F (* pop ds *)
/$5F (* pop di *)
/$5E (* pop si *)
/$5A (* pop dx *)
/$59 (* pop cx *)
/$5B (* pop bx *)
/$58 (* pop ax *)
/$CB) (* retf *)
END;
PROCEDURE Set_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $26;
es := Seg(Routine);
di := Ofs(Routine);
dx := CommPort;
Intr($14,Dos.Registers(reg88));
Utilise := (al=1);
Segment := es;
Offset := di
END;
END
END;
PROCEDURE Reset_routine(Segment,Offset: WORD);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $26;
es := Segment;
di := Offset;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Unset_routine;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $27;
dx := CommPort;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Err_Routine; INTERRUPT;
(* !! ATTENTION !! DO NOT USE ANY LOCAL VARIABLE TO MAKE THIS ROUTINE *)
(* THAT MUST BE FULLY RE-ENTRANT... *)
BEGIN
(* Install here the function to manage the Int. 14h errors. *)
(* Never call the DOS interrupt 21h !... *)
(* "reg88.dx" gives you the port number eventually designated *)
(* when the function 14h (making the error) has been called...*)
(* ... *)
(* The following special code MUST NOT BE CHANGED !... *)
INLINE($89/$EC (* mov sp,bp *)
/$5D (* pop bp *)
/$07 (* pop es *)
/$1F (* pop ds *)
/$5F (* pop di *)
/$5E (* pop si *)
/$5A (* pop dx *)
/$59 (* pop cx *)
/$5B (* pop bx *)
/$58 (* pop ax *)
/$CB) (* retf *)
END;
PROCEDURE Set_err_routine(VAR Utilise: BOOLEAN; VAR Segment,Offset: WORD);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $28;
es := Seg(Err_Routine);
di := Ofs(Err_Routine);
Intr($14,Dos.Registers(reg88));
Utilise := (al=1);
Segment := es;
Offset := di
END;
END
END;
PROCEDURE Reset_err_routine(Segment,Offset: WORD);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $28;
es := Segment;
di := Offset;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Unset_err_routine;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $29;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Verrouille;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $2A;
al := 1;
bl := 1;
Intr($14,Dos.Registers(reg88))
END;
END
END;
PROCEDURE Deverrouille;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $2A;
al := 1;
bl := 0;
Intr($14,Dos.Registers(reg88))
END;
END
END;
FUNCTION GetDeviceName: BYTE;
VAR
Nom : STRING[8] ;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $2B;
es := Seg(Nom[1]);
di := Ofs(Nom[1]);
Intr($14,Dos.Registers(reg88));
IF ah=0 THEN NomDevice := Nom;
GetDeviceName := ah
END;
END
END;
FUNCTION GetPortDevice: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 0;
ah := $2C;
Intr($14,Dos.Registers(reg88));
IF ah=0 THEN GetPortDevice := al
ELSE GetPortDevice := ah
END;
END
END;
FUNCTION ResetPortDevice: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 1;
ah := $2C;
dx := CommPort;
Intr($14,Dos.Registers(reg88));
ResetPortDevice := ah
END;
END
END;
FUNCTION EmulBIOS: BOOLEAN;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 0;
ah := $2D;
Intr($14,Dos.Registers(reg88));
IF al=1 THEN EmulBIOS := TRUE ELSE EmulBIOS := FALSE
END;
END
END;
PROCEDURE SetEmulBIOS(status: BOOLEAN);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 1;
ah := $2D;
IF status THEN bl := 1 ELSE bl := 0;
Intr($14,Dos.Registers(reg88))
END;
END
END;
FUNCTION OrdiType: BYTE;
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 0;
ah := $2E;
Intr($14,Dos.Registers(reg88));
OrdiType := bl
END;
END
END;
PROCEDURE SetOrdiType(OrdiType: BYTE);
BEGIN
IF RS_accessible THEN
BEGIN
WITH reg88 DO
BEGIN
al := 1;
ah := $2E;
bl := OrdiType;
Intr($14,Dos.Registers(reg88))
END;
END
END;
FUNCTION Open_COMM: WORD;
BEGIN
IF NOT COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $3D;
ds := Seg(NomDevice[1]);
dx := Ofs(NomDevice[1]);
al := 2;
msdos(Dos.Registers(reg88));
IF (Flags AND 1)<>0 THEN
Open_COMM := ax
ELSE
BEGIN
Open_COMM := 0;
handler_voie_serie := ax;
COMM_ouvert := TRUE
END;
END
END;
END;
FUNCTION Close_COMM: INTEGER;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $3E;
bx := handler_voie_serie;
msdos(Dos.Registers(reg88));
IF (Flags AND 1)<>0 THEN
Close_COMM := ax
ELSE
BEGIN
Close_COMM := 0;
COMM_ouvert := FALSE
END;
END;
END
ELSE Close_COMM := -1
END;
FUNCTION IOStream_READ(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
VAR
buff : ARRAY[1..11] OF BYTE ;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $44;
al := 2;
cx := 11;
ds := Seg(buff[1]);
dx := Ofs(buff[1]);
bx := handler_voie_serie;
msdos(Dos.Registers(reg88));
IF (Flags AND 1)=0 THEN
BEGIN
Voie_active := Chr(buff[1]+1);
Format := (buff[2] * 256) + buff[3];
RTS_type := Chr(buff[4]);
DTR_type := Chr(buff[5]);
RI_type := Chr(buff[6]);
DCD_type := Chr(buff[7]);
OUT1_type := Chr(buff[8]);
Xonoff_type := Chr(buff[9]);
Xon := buff[10];
Xoff := buff[11];
IOStream_READ := FALSE;
END
ELSE IOStream_READ := TRUE;
END
END;
END;
FUNCTION IOStream_WRITE(VAR Voie_active: CHAR;VAR Format: WORD; VAR RTS_type,
DTR_type, RI_type, DCD_type, OUT1_type, Xonoff_type: CHAR): BOOLEAN;
VAR
buff : ARRAY[1..11] OF BYTE ;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
buff[1] := Ord(Voie_active)-$30-1;
ax := Format;
buff[2] := ah;
buff[3] := al;
buff[4] := Ord(RTS_type);
buff[5] := Ord(DTR_type);
buff[6] := Ord(RI_type);
buff[7] := Ord(DCD_type);
buff[8] := Ord(OUT1_type);
buff[9] := Ord(Xonoff_type);
buff[10] := Xon;
buff[11] := Xoff;
ah := $44;
al := 3;
cx := 11;
ds := Seg(buff[1]);
dx := Ofs(buff[1]);
bx := handler_voie_serie;
msdos(Dos.Registers(reg88));
IF (Flags AND 1)=0 THEN IOStream_WRITE := FALSE
ELSE IOStream_WRITE := TRUE;
END;
END
END;
FUNCTION CheckCOMMIn: BOOLEAN;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $44;
al := 6;
bx := handler_voie_serie;
msdos(Dos.Registers(reg88));
IF al=0 THEN CheckCOMMIn := TRUE
ELSE CheckCOMMIn := FALSE;
END;
END
ELSE CheckCOMMIn := FALSE;
END;
FUNCTION CheckCOMMOut: BOOLEAN;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $44;
al := 7;
bx := handler_voie_serie;
msdos(Dos.Registers(reg88));
IF al=0 THEN CheckCOMMOut := TRUE
ELSE CheckCOMMOut := FALSE;
END;
END
ELSE CheckCOMMOut := FALSE;
END;
FUNCTION ReadCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $3F;
bx := handler_voie_serie;
cx := nombre;
ds := Seg(c);
dx := Ofs(c);
msdos(Dos.Registers(reg88));
IF (Flags AND 1)<>0 THEN
ReadCOMM := ax
ELSE
IF ax<>0 THEN ReadCOMM := 0
ELSE ReadCOMM := -1;
END;
END
END;
FUNCTION WriteCOMM(VAR c: CHAR; nombre: WORD): INTEGER;
BEGIN
IF COMM_ouvert THEN
BEGIN
WITH reg88 DO
BEGIN
ah := $40;
bx := handler_voie_serie;
ds := Seg(c);
dx := Ofs(c);
cx := nombre;
msdos(Dos.Registers(reg88));
IF (Flags AND 1)<>0 THEN
WriteCOMM := ax
ELSE
IF ax<>0 THEN WriteCOMM := 0
ELSE WriteCOMM := -1;
END;
END
END;
FUNCTION Check_STARCOMM_Present: BYTE;
VAR
Check : BYTE ;
BEGIN
Check := 0;
WITH reg88 DO
BEGIN
ah := 6;
al := 0;
Intr($14,Dos.Registers(reg88));
IF al<>0 THEN
BEGIN
RS_accessible := TRUE;
Check := 1;
END
ELSE RS_accessible := FALSE
END;
IF RS_accessible THEN
IF GetDeviceName=0 THEN Check := 2;
Check_STARCOMM_Present := Check
END;
BEGIN
COMM_ouvert := FALSE; (* The DEVICE port is NOT open. *)
type_driver := Check_STARCOMM_Present;
IF type_driver<>0 THEN Get_Ports_Adresses
END.